#ifndef ETAT_H
#define ETAT_H

#include <QtCore>

class Pion;
class BoardWidget;
class Continent;
class Joueur;
class Frontiere;
class PlateauRisQ;

/**
 * @author TAFFOREAU PERIGNON
 * @brief Représente un état du jeu
 */
class Etat : public QObject
{
    Q_OBJECT

public:
    Etat(int id, QString nom, Continent *continent, PlateauRisQ *plateau);

    /**
     * @brief Ajoute le pion à l'état et lève
     * le signal void nouveauPion(Pion *p)
     *
     * @param pion
     */
    void addPion(Pion *pion);

    /**
     * @brief Supprime le pion de l'état et lève
     * le signal void supprimerPion(Pion *p)
     *
     * @param pion
     */
    void removePion(Pion *pion);

    /**
     * @brief Supprime le dernier pion de l'état et lève
     * le signal void supprimerPion(Pion *p)
     *
     */
    void removeLastPion();

    /**
     * @brief Met à jour la position des pions autour de l'état
     *
     */
    void adjustPion();


    /**
     * @brief Met à jour la position des frontières autour de
     * l'état (utiles lorsqu'il y a les flèches )
     *
     */
    void adjustFrontiere();

    /**
     * @brief Vérifie que le pion est lié par une frontière
     * à l'état et appartient au même joueur
     *
     * @param pion
     * @return true si le pion est voisin de l'état et appartient au même joueur
     */
    bool canMove(Pion *pion);

    /**
     * @brief Vérifie que l'état est lié par une frontière
     * à l'état et appartient au même joueur
     *
     * @param pion
     * @return true si l'état et voisin de l'état et appartient au même joueur
     */
    bool canMove(Etat *etat);

    /**
     * @brief Retourne la liste des frontières
     *
     * @return QList<Frontiere *> La liste des frontières
     */
    QList<Frontiere *> frontieres(){
        return frontieresList;
    }

    /**
     * @brief Ajoute une frontière à l'état
     *
     * @param frontiere
     */
    void addFrontiere(Frontiere *frontiere){
        frontieresList << frontiere;
    }

    /**
     * @brief Retourne le joueur associé à l'état
     *
     * @return Joueur * Un joueur si état associé sinon NULL
     */
    Joueur *getJoueur(){
        return joueur;
    }

    /**
     * @brief Change le joueur qui possède l'état et lève updateGraphics()
     *
     * @param j
     */
    void setJoueur(Joueur *j);


    /**
     * @brief Retourne le nom de l'état
     *
     * @return QString
     */
    QString getNom(){
        return nom;
    }

    /**
     * @brief Retourne l'id de l'état
     *
     * @return int
     */
    int getId(){
        return id;
    }

    /**
     * @brief Retourne le continent de l'état
     *
     * @return Continent *
     */
    Continent *getContinent(){
        return continent;
    }

    /**
     * @brief Retourne le plateau de jeu
     *
     * @return PlateauRisQ *
     */
    PlateauRisQ *getPlateau(){
        return plateau;
    }

    /**
     * @brief Retourne les pions associés à l'état
     *
     * @return QList<Pion *>
     */
    QList<Pion *> pions(){
        return pionsList;
    }

    /**
     * @brief Set la position de l'état sur le plateau et
     * adjust les frontières et les pions
     *
     * @param x
     * @param y
     */
    void setPos(int x, int y){
        this->x = x; this->y = y;
        adjustFrontiere();
        adjustPion();
    }

    /**
     * @brief Retourne la position de l'état sur le plateau
     *
     * @return const QPointF
     */
    const QPointF pos(){ return QPointF(x, y);}

signals:
    /**
     * @brief Emit lorsque l'état doit être redessiné
     * ( ex: lors d'un changement de joueur )
     *
     */
    void updateGraphics();

    /**
     * @brief Emit lors de l'ajout d'un pion
     *
     * @param p
     */
    void nouveauPion(Pion *p);

    /**
     * @brief Emit lors de la suppréssion d'un pion
     *
     * @param p
     */
    void supprimerPion(Pion *p);
    
    void ChangeStatut();

protected:
    int id, x, y;
    QString nom;
    Continent *continent;
    Joueur *joueur;
    PlateauRisQ *plateau;

    QList<Pion *> pionsList;
    QList<Frontiere *> frontieresList;
};

/**
 * @brief Représente les continents
 *
 */
class Continent
{
public:
    int id;
    QString nom;

    QList<Etat *> etats(){
        return etatsList;
    }

    void addEtats(Etat* eta)
    {
        etatsList.append(eta);
    }

protected:
    QList<Etat *> etatsList;
};

#endif // ETAT_H
